#include <stdio.h>

#include <QtGui>

#include "environmentdialog.h"

using namespace PBVP;

EnvironmentDialog::EnvironmentDialog(const Environment& env, QWidget *parent)
    : m_Env(env), QDialog(parent)
{
    ui.setupUi(this);

	cullGroup = new QButtonGroup(this);
	cullGroup->addButton(ui.cullBackButton);
	cullGroup->setId(ui.cullBackButton, 0);
	cullGroup->addButton(ui.cullFrontButton);
	cullGroup->setId(ui.cullFrontButton, 1);
	cullGroup->addButton(ui.noCullButton);
	cullGroup->setId(ui.noCullButton, 2);
	CullMode cullMode = m_Env.cullmode();
	switch(cullMode) {
	case CULL_BACK:
		ui.cullBackButton->setChecked(true);
		break;
	case CULL_FRONT:
		ui.cullFrontButton->setChecked(true);
		break;
	case NO_CULL:
		ui.noCullButton->setChecked(true);
		break;
	}
	connect(cullGroup, SIGNAL(buttonClicked(int)), this, SLOT(setCullMode()));
	
	ui.bgColorView->setColor(m_Env.backgorundColor().toQColor());
	connect(ui.bgColorView, SIGNAL(colorChanged(QColor)), this, SLOT(setBgColor(QColor)));

	ui.defColorView->setColor(m_Env.defaultColor().toQColor());
	connect(ui.defColorView, SIGNAL(colorChanged(QColor)), this, SLOT(setDefColor(QColor)));

	ui.materialAmbientView->setColor(m_Env.material().ambient().toQColor());
	connect(ui.materialAmbientView, SIGNAL(colorChanged(QColor)), 
		this, SLOT(setMatAmbient(QColor)));
	ui.materialDiffuseView->setColor(m_Env.material().diffuse().toQColor());
	connect(ui.materialDiffuseView, SIGNAL(colorChanged(QColor)), 
		this, SLOT(setMatDiffuse(QColor)));
	ui.materialSpecularView->setColor(m_Env.material().specular().toQColor());
	connect(ui.materialSpecularView, SIGNAL(colorChanged(QColor)),
		this, SLOT(setMatSpecular(QColor)));
	ui.materialEmissionView->setColor(m_Env.material().emission().toQColor());
	connect(ui.materialEmissionView, SIGNAL(colorChanged(QColor)),
		this, SLOT(setMatEmission(QColor)));
	QString str;
	ui.materialShinessEdit->setText(str.setNum(m_Env.material().shiness()));
	connect(ui.materialShinessEdit, SIGNAL(textChanged(const QString&)),
		this, SLOT(setMatShiness(const QString&)));

	// Set up light list
	for(unsigned int i = 0; i < m_Env.numOfLights(); i++) {
		QString lit;
		ui.lightList->addItem(lit.setNum(i).prepend("Light "));
	}
	connect(ui.lightList, SIGNAL(itemClicked(QListWidgetItem *)),
		this, SLOT(showLightAttributes()));
	connect(ui.lightAmbientView, SIGNAL(colorChanged(const QColor&)), 
		this, SLOT(setLightAmbient(const QColor&)));
	connect(ui.lightDiffuseView, SIGNAL(colorChanged(const QColor&)),
		this, SLOT(setLightDiffuse(const QColor&)));
	connect(ui.lightSpecularView, SIGNAL(colorChanged(const QColor&)),
		this, SLOT(setLightSpecular(const QColor&)));
	connect(ui.xLightEdit, SIGNAL(editingFinished()), 
		this, SLOT(setLightPosition()));
	connect(ui.yLightEdit, SIGNAL(editingFinished()), 
		this, SLOT(setLightPosition()));
	connect(ui.zLightEdit, SIGNAL(editingFinished()), 
		this, SLOT(setLightPosition()));
	connect(ui.wLightEdit, SIGNAL(editingFinished()), 
		this, SLOT(setLightPosition()));
	connect(ui.lightAddButton, SIGNAL(pressed()), this, SLOT(addLight()));
	connect(ui.lightDeleteButton, SIGNAL(pressed()), this, SLOT(deleteLight()));
	connect(ui.lightEnabledBox, SIGNAL(stateChanged(int)), this, SLOT(turnLightOnOff()));
	errorMessage = new QErrorMessage(this);
}

//////////////////////////////////////////////////////////////////////////
// Public slots
//////////////////////////////////////////////////////////////////////////
void EnvironmentDialog::setCullMode()
{
	int id = cullGroup->checkedId();
	switch(id) {
	case 0:
		m_Env.setCullMode(CULL_BACK);
		break;
	case 1:
		m_Env.setCullMode(CULL_FRONT);
		break;
	case 2:
		m_Env.setCullMode(NO_CULL);
		break;
	}
}

void EnvironmentDialog::setBgColor(const QColor& color)
{
	Color c( color);
	m_Env.setBackgroundColor(c);
}

void EnvironmentDialog::setDefColor(const QColor& color)
{
	Color c (color);
	m_Env.setDefColor(c);
}

void EnvironmentDialog::setMatAmbient(const QColor& color)
{
	Color c(color);
	m_Env.material().setAmbient(c);
}

void EnvironmentDialog::setMatDiffuse(const QColor& color)
{
	Color c(color);
	m_Env.material().setDiffuse(c);
}

void EnvironmentDialog::setMatSpecular(const QColor& color)
{
	Color c(color);
	m_Env.material().setSpecular(c);
}

void EnvironmentDialog::setMatEmission(const QColor& color)
{
	Color c(color);
	m_Env.material().setEmission(c);
}

void EnvironmentDialog::setMatShiness(const QString& str)
{
	float shiness = str.toFloat();
	m_Env.material().setShiness(shiness);
}

void EnvironmentDialog::showLightAttributes()
{
	int i = ui.lightList->currentRow();
	if (i < 0) return;
	Light& currentLight = m_Env.light(i);
	if(currentLight.isOn()) {
		ui.lightEnabledBox->setChecked(true);
	} else {
		ui.lightEnabledBox->setChecked(false);
	}
	ui.lightAmbientView->setColor(currentLight.ambient().toQColor());
	ui.lightDiffuseView->setColor(currentLight.diffuse().toQColor());
	ui.lightSpecularView->setColor(currentLight.specular().toQColor());
	QString str;
	ui.xLightEdit->setText(str.setNum(currentLight.position().x));
	ui.yLightEdit->setText(str.setNum(currentLight.position().y));
	ui.zLightEdit->setText(str.setNum(currentLight.position().z));
	ui.wLightEdit->setText(str.setNum(currentLight.position().w));
}

void EnvironmentDialog::setLightAmbient(const QColor &color)
{
	int i = ui.lightList->currentRow();
	if(i < 0) return;
	Light& currentLight = m_Env.light(i);
	currentLight.setAmbient(Color(color));
}

void EnvironmentDialog::setLightDiffuse(const QColor &color)
{
	int i = ui.lightList->currentRow();
	if(i < 0) return;
	Light& currentLight = m_Env.light(i);
	currentLight.setDiffuse(Color(color));
}

void EnvironmentDialog::setLightSpecular(const QColor &color)
{
	int i = ui.lightList->currentRow();
	if(i < 0) return;
	Light& currentLight = m_Env.light(i);
	currentLight.setSpecular(Color(color));
}

void EnvironmentDialog::setLightPosition()
{
	Vector4 pos;
	pos.x = ui.xLightEdit->text().toFloat();
	pos.y = ui.yLightEdit->text().toFloat();
	pos.z = ui.zLightEdit->text().toFloat();
	pos.w = ui.wLightEdit->text().toFloat();
	Light& currentLight = m_Env.light(ui.lightList->currentRow());
	currentLight.setPosition(pos);
}

void EnvironmentDialog::turnLightOnOff()
{
	int i = ui.lightList->currentRow();
	if(i < 0) return;
	bool enableChecked = ui.lightEnabledBox->isChecked();
	Light& currentLight = m_Env.light(i);
	currentLight.turnOnOff(enableChecked);
}

void EnvironmentDialog::addLight()
{
	if (m_Env.numOfLights() >= Environment::MAX_LIGHT_COUNT)
	{
		errorMessage->showMessage(tr("Maximum number of lights have been added"));
		return;
	}
	Light lit;
	int i = m_Env.numOfLights();
	m_Env.addLight(lit);
	QString str;
	ui.lightList->addItem(str.setNum(i).prepend("Light "));
	ui.lightList->setCurrentRow(i);
	showLightAttributes();
}

void EnvironmentDialog::deleteLight()
{
	int i = ui.lightList->currentRow();
	if(i < 0) return;
	m_Env.removeLight(i);
	QListWidgetItem* curItem = ui.lightList->currentItem();
	ui.lightList->clear();
	// Set up light list
	for(unsigned int i = 0; i < m_Env.numOfLights(); i++) {
		QString lit;
		ui.lightList->addItem(lit.setNum(i).prepend("Light "));
	}
}